The commands in this chapter all use two-letter sequences beginning with the b prefix.
The “binary” operations actually work regardless of the currently displayed radix, although their results make the most sense in a radix like 2, 8, or 16 (as obtained by the d 2, d 8, or d 6 commands, respectively). You may also wish to enable display of leading zeros with d z. See Radix Modes.
The Calculator maintains a current word size ‘w’, an arbitrary positive or negative integer. For a positive word size, all of the binary operations described here operate modulo ‘2^w’. In particular, negative arguments are converted to positive integers modulo ‘2^w’ by all binary functions.
If the word size is negative, binary operations produce twos-complement integers from ‘-(2^(-w-1))’ to ‘2^(-w-1)-1’ inclusive. Either mode accepts inputs in any range; the sign of ‘w’ affects only the results produced.
The b c (calc-clip)
[clip] command can be used to clip a number by
reducing it modulo ‘2^w’. The commands described in this
chapter automatically clip their results to the current word
size. Note that other operations like addition do not use the
current word size, since integer addition generally is not
“binary.” (However, see Simplification
Modes, calc-bin-simplify-mode.) For example,
with a word size of 8 bits b c converts a number to
the range 0 to 255; with a word size of -8 b c
converts to the range -128 to 127.
The default word size is
32 bits. All operations except the shifts and rotates allow you
to specify a different word size for that one operation by giving
a numeric prefix argument: C-u 8 b c clips the top of
stack to the range 0 to 255 regardless of the current word size.
To set the word size permanently, use b w
(calc-word-size). This command displays a prompt
with the current word size; press <RET> immediately to keep
this word size, or type a new word size at the prompt.
When the binary operations are written in symbolic form, they take an optional second (or third) word-size parameter. When a formula like ‘and(a,b)’ is finally evaluated, the word size current at that time will be used, but when ‘and(a,b,-8)’ is evaluated, a word size of -8 will always be used. A symbolic binary function will be left in symbolic form unless the all of its argument(s) are integers or integer-valued floats.
If either or both arguments are modulo forms for which ‘M’ is a power of two, that power of two is taken as the word size unless a numeric prefix argument overrides it. The current word size is never consulted when modulo-power-of-two forms are involved.
The b a
(calc-and) [and] command computes the
bitwise AND of the two numbers on the top of the stack. In other
words, for each of the ‘w’ binary digits of the two numbers
(pairwise), the corresponding bit of the result is 1 if and only
if both input bits are 1: ‘and(2#1100, 2#1010) = 2#1000’.
The b o
(calc-or) [or] command computes the
bitwise inclusive OR of two numbers. A bit is 1 if either of the
input bits, or both, are 1: ‘or(2#1100, 2#1010) = 2#1110’.
The b x
(calc-xor) [xor] command computes the
bitwise exclusive OR of two numbers. A bit is 1 if exactly one of
the input bits is 1: ‘xor(2#1100,
2#1010) = 2#0110’.
The b d (calc-diff)
[diff] command computes the bitwise difference of
two numbers; this is defined by ‘diff(a,b) = and(a,not(b))’, so that
‘diff(2#1100, 2#1010) =
2#0100’.
The b n
(calc-not) [not] command computes the
bitwise NOT of a number. A bit is 1 if the input bit is 0 and
vice-versa.
The b l
(calc-lshift-binary) [lsh] command
shifts a number left by one bit, or by the number of bits
specified in the numeric prefix argument. A negative prefix
argument performs a logical right shift, in which zeros are
shifted in on the left. In symbolic form,
‘lsh(a)’ is
short for ‘lsh(a,1)’, which in turn is short for
‘lsh(a,n,w)’.
Bits shifted “off the end,” according to the current
word size, are lost.
The H b l command also does a left shift, but it takes two arguments from the stack (the value to shift, and, at top-of-stack, the number of bits to shift). This version interprets the prefix argument just like the regular binary operations, i.e., as a word size. The Hyperbolic flag has a similar effect on the rest of the binary shift and rotate commands.
The b r
(calc-rshift-binary) [rsh] command
shifts a number right by one bit, or by the number of bits
specified in the numeric prefix argument:
‘rsh(a,n) =
lsh(a,-n)’.
The b L
(calc-lshift-arith) [ash] command
shifts a number left. It is analogous to lsh, except
that if the shift is rightward (the prefix argument is negative),
an arithmetic shift is performed as described below.
The b R
(calc-rshift-arith) [rash] command
performs an “arithmetic” shift to the right, in which
the leftmost bit (according to the current word size) is
duplicated rather than shifting in zeros. This corresponds to
dividing by a power of two where the input is interpreted as a
signed, twos-complement number. (The distinction between the
‘rsh’ and
‘rash’
operations is totally independent from whether the word size is
positive or negative.) With a negative prefix argument, this
performs a standard left shift.
The b t
(calc-rotate-binary) [rot] command
rotates a number one bit to the left. The leftmost bit (according
to the current word size) is dropped off the left and shifted in
on the right. With a numeric prefix argument, the number is
rotated that many bits to the left or right.
See Set Operations, for the b p and b u commands that pack and unpack binary integers into sets. (For example, b u unpacks the number ‘2#11001’ to the set of bit-numbers ‘[0, 3, 4]’.) Type b u V # to count the number of “1” bits in a binary integer.
Another interesting use of the set representation of binary integers is to reverse the bits in, say, a 32-bit integer. Type b u to unpack; type 31 <TAB> - to replace each bit-number in the set with 31 minus that bit-number; type b p to pack the set back into a binary integer.